Ajax-XMLHttpRequest Level2

12次阅读
没有评论

共计 3917 个字符,预计需要花费 10 分钟才能阅读完成。

旧版 XMLHttpRequest 的缺点

  1. 只支持文本数据的传输,无法用来读取和上传文件
  2. 传输和接收数据时,没有进度信息,只能提示有没有完成

XMLHttpRequest Level2 新功能

  1. 可以设置 HTTP 请求的时限
  2. 可以使用 FormData 对象管理表单数据
  3. 可以上传文件
  4. 可以获得数据传输的进度信息

设置HTTP请求时限

有时,Ajax 操作很耗时,而且无法预知要耗费多长时间;如果用户网速很慢,可能要等很久;新版本的 XMLTttpRequest 对象,增加了 timeout 属性,可以设置 HTTP 请求的时限:

    xhr.timeout = 3000

上面的语句,将最长等待时间设置为 3000 毫秒,超过了这个时限,就会自动停止 HTTP 请求;与之配套的还有一个 ontimeout 事件,用来指定回调函数:

    xhr.ontimeout = function(e) {
        alert('请求超时!')
    }

FormData 对象管理表单数据

AJax操作往往用来提交表单数据,为了方便表单处理,HTML5新增了FormData对象,可以模拟表单操作:

        // 获取表单元素
        var form = document.querySelector('#form1')

        // 监听表单元素的 submit 事件
        form.addEventListener('submit', function (e) {
            // 阻止默认提交行为
            e.preventDefault()

            // 根据form表单创建 FormData 对象,会自动将表单数据填充到 FormData对象中
            var fd = new FormData(form)

            var xhr = new XMLHttpRequest()
            xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
            xhr.send(fd)
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(JSON.parse(xhr.responseText))
                }
            }
        })

上传文件

  1. 定义 UI 结构
  2. 验证是否选择了文件
// 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload')
// 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
    // 获取到文件列表
    var files = document.querySelector('#filel').files
    if(flies.length <= 0 ) {
        return alert('请选择要上传的文件')
    }
    // ...后续业务逻辑
})
  1. 向 FormData中追加文件
// 创建 FormData 对象
var fd = new FormData()
// 向 FormData 中追加文件
fd.append('avatar', files[0])
  1. 使用 xhr 发起带文件的请求
// 创建xhr对象 
var xhr = new XMLHttpRequest()
// 调用open函数,指定请求类型与URL地址;其中请求类型必须为POST
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
// 发起请求
xhr.send(fd)
  1. 监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 200) {
        var data = JSON.parse(xhr.responseText)
        if(data.status === 200) {
            // 文件上传成功
            // 将服务器返回的图片地址,设置为<img>的 src 属性
            document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
        } else {
            // 图片上传失败
            alert('图片上传失败: '+ data.message)
        }
    }
}
// 获取上传文件的按钮
var btnUpload = document.querySelector('#btnUpload')
// 为按钮添加 click 事件监听
btnUpload.addEventListener('click', function() {
    // 获取到文件列表
    var files = document.querySelector('#filel').files
    if(flies.length <= 0 ) {
        return alert('请选择要上传的文件')
    }

    // 创建 FormData 对象
    var fd = new FormData()
    // 向 FormData 中追加文件
    fd.append('avatar', files[0])

    // 创建xhr对象 
    var xhr = new XMLHttpRequest()
    // 调用open函数,指定请求类型与URL地址;其中请求类型必须为POST
    xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar')
    // 发起请求
    xhr.send(fd)

    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4 && xhr.status === 200) {
            var data = JSON.parse(xhr.responseText)
            if(data.status === 200) {
                // 文件上传成功
                // 将服务器返回的图片地址,设置为<img>的 src 属性
                document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url
            } else {
                // 图片上传失败
                alert('图片上传失败: '+ data.message)
            }
        }
    }
})

显示文件上传进度

新版本的 XMLHttpRequest 对象中,可以通过监听 xhr.upload.onprogress 事件,来获取到文件的上传进度

// 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 监听 xhr.upload 的 onprogress 事件
xhr.upload.onprogress = function(e) {
    // e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
    if(e.lengthComputable) {
        // e.loaded 以传输字节
        // e.total 需传输的总字节
        var percentComplete = Math.cell((e.loaded / e.total) * 100)
    }
}

监听上传完成的事件

xhr.upload.onload = function() {
    // 移除上传中的类样式
    // 添加上传完成的类样式
    $('#percent').removeClass().addClass('progress-bar progress-bar-success progress-bar-striped active')
}

使用 jQuery 完成文件上传

ajaxStart(callback)

Ajax请求开始时,执行 ajaxStart 函数; 可以在 ajaxStar 的callback中显示loading效果:

// 自 jQuery 版本 1.8起, 该方法只能被附加到文档上
$(document).ajaxStart(function() {
    $('#loading').show()
})

$(document).ajaxStart() 函数会监听当前文档内所有的Ajax请求

ajaxStop(callback)

Ajax请求结束时,执行 ajaxStop 函数; 可以在 ajaxStar 的callback中隐藏loading效果:

// 自 jQuery 版本 1.8起, 该方法只能被附加到文档上
$(document).ajaxStop(function() {
    $('#loading').hide()
})
$(function () {
    // 监听到Ajax请求被发起了
    $(document).ajaxStart(function () {
        $('#loading').show()
    })

    // 监听到Ajax完成的事件
    $(document).ajaxStop(function () {
        $('#loading').hide()
    })

    $('#btnUpload').on('click', function () {
        // 将 jQuery 对象转换为 DOM 对象,并获取选中文件列表
        var files = $('#file')[0].files
        // 判断是否选择了文件
        if (files.length <= 0) {
            return alert('请选择文件!')
        }
        // 向 FormData 中追加文件
        var fd = new FormData()
        fd.append('avatar', files[0])

        $.ajax({
            method: 'POST',
            url: 'http://www.liulongbin.top:3006/api/upload/avatar',
            data: fd,
            // 不修改 Content-Type 属性,使用 FormData 默认的 Content-Type 值
            contentType: false,
            // 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发送到服务器
            processData: false,
            success: function (res) {
                console.log(res)
            }
        })
    })
})

正文完
 0
qiaofugui.cn
版权声明:本站原创文章,由 qiaofugui.cn 于2024-05-21发表,共计3917字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码